package com.panopset.app.scrambler;

import static com.panopset.Util.dspmsg;
import static com.panopset.Util.x;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;

import com.panopset.compat.Strings;
import com.panopset.TextScrambler;
import com.panopset.Util;
import com.panopset.sf.FontManager;
import com.panopset.sf.TitledTextArea;
import com.panopset.sf.Windoc;

public class MainPanelDoc {

    private final Windoc w;

    public MainPanelDoc(final Windoc windoc) {
        w = windoc;
    }
    /**
     * gui.
     */
    private JPanel gui;

    /**
     * @return gui.
     */
    public JPanel getGui() {
        if (gui == null) {
            gui = w.cf.createPanel(new BorderLayout());
            gui.add(BorderLayout.NORTH, assembleNorthPanel());
            gui.add(BorderLayout.CENTER, assembleCenterPanel());
        }
        return gui;
    }

    void encrypt() {
        dspmsg("");
        if (!Strings.isPopulated(getPlainTextTA().getText().trim())) {
            return;
        }
        getEncryptedTA().setText(
                TextScrambler.scramble(getPlainTextTA().getText(), new String(
                        getPasswordTF().getPassword())));
    }

    void decrypt() {
        if (isPanicking()) {
            return;
        }
        if (!Strings.isPopulated(getEncryptedTA().getText().trim())) {
            return;
        }
        dspmsg("");
        getPlainTextTA().setText(
                TextScrambler.unscramble(
                        getEncryptedTA().getText().replace(" ", ""),
                        new String(getPasswordTF().getPassword())));
    }

    private JPanel assembleNorthPanel() {
        JPanel fl = w.cf.createPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 0.0;
        fl.add(getPanicButton(), gbc);
        gbc.gridx++;
        fl.add(getClearButton(), gbc);
        gbc.gridx++;
        gbc.weightx = 1.0;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        fl.add(getPasswordTF(), gbc);
        return fl;
    }

    String panicText = "";
    static final String PANIC_ON_TIP = "*" + Util.x("whew") + "* "
            + Util.x("All clear, bring the message back") + ".";
    static final String PANIC_OFF_TIP = Util.x("Someone coming!") + " "
            + Util.x("Hide unscrambled text") + "!!";
    static final String PANIC_ON_TEXT_TIP = Util.x("Text currently hidden by")
            + " \"" + Util.x("panic button") + "\", " + Util.x("press") + "\""
            + Util.x("don't panic") + "\"" + Util.x("to bring it back") + ".";
    static final String PANIC_OFF_TEXT_TIP = Util.x("Unscrambled text");

    void clear() {
        getPlainTextTA().setText("");
        getEncryptedTA().setText("");
    }

    void panic() {
        if (isPanicking()) {
            getPanicButton().setText(PANIC_OFF);
            getPlainTextTA().setText(panicText);
            getPlainTextTA().setToolTipText(PANIC_OFF_TEXT_TIP);
            getPlainTextTA().setEditable(true);
        } else {
            getPanicButton().setText(PANIC_ON);
            panicText = getPlainTextTA().getText();
            getPlainTextTA().setToolTipText(PANIC_ON_TEXT_TIP);
            getPlainTextTA().setText("");
            getPlainTextTA().setEditable(false);
        }
    }

    boolean isPanicking() {
        return getPanicButton().getText().equals(PANIC_ON);
    }

    static String PANIC_OFF = Util.x("Panic");
    static String PANIC_ON = Util.x("Don't panic");

    JButton clearButton;

    private JButton getClearButton() {
        if (clearButton == null) {
            clearButton = new JButton(Util.x("Clear"));
            clearButton.setToolTipText(

            Util.x("Clear both scrambled and unscrambled text") + ".");
            clearButton.setMnemonic(KeyEvent.VK_C);
            clearButton.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent arg0) {
                    clear();
                }

            });
            w.cf.registerPassiveComponent(clearButton);
        }
        return clearButton;
    }

    /**
     * Panic button.
     */
    private JButton panicButton;

    /**
     *
     * @return Panic button
     */
    private JButton getPanicButton() {
        if (panicButton == null) {
            panicButton = new JButton(PANIC_OFF);
            panicButton.setToolTipText(PANIC_OFF_TIP);
            panicButton.setMnemonic(KeyEvent.VK_P);
            panicButton.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(final ActionEvent arg0) {
                    panic();
                }

            });
            w.cf.registerPassiveComponent(panicButton);
        }
        return panicButton;
    }

    private JTabbedPane assembleCenterPanel() {
        JTabbedPane rtn = new JTabbedPane();
        FontManager.getInstance().register(rtn, FontManager.FontType.boldArial);
        JPanel mp = w.cf.createPanel(new GridLayout(2, 1));
        JPanel tp0 = w.cf.createTitledPanel(new GridLayout(1, 1),
                x("Plain Text Message"), PANIC_OFF_TEXT_TIP);
        tp0.add(new JScrollPane(getPlainTextTA()));
        mp.add(tp0);
        mp.add(getEncryptedTA().getPanel());
        JPanel adv = assembleAdvancedPanel();
        rtn.add(mp);
        rtn.add(adv);
        return rtn;
    }

    private JPanel assembleAdvancedPanel() {
        JPanel rtn = w.cf.createPanel(new BorderLayout());
        rtn.add(BorderLayout.NORTH, assembleAdvancedNorthPanel());
        rtn.add(BorderLayout.CENTER, assembleAdvancedCenterPanel());
        rtn.setName(x("Advanced"));
        return rtn;
    }

    /**
     * Private computer.
     */
    private static final String PRIVATE_COMPUTER = Util.x("Private computer");

    /**
     * Private computer tip text.
     */
    private static final String PRIVATE_COMPUTER_TIP = Util.x("If you check"
            + " this box")
            + ", " + Util.x("your password will be saved between launches") + ".";

    private JPanel assembleAdvancedNorthPanel() {
        JPanel rtn = w.cf.createPanel(new FlowLayout());
        rtn.add(getPrivateComputer());
        return rtn;
    }

    /**
     * Private computer checkbox.
     */
    private JCheckBox privateComputer;

    /**
     *
     * @return Private computer checkbox.
     */
    public JCheckBox getPrivateComputer() {
        if (privateComputer == null) {
            privateComputer = w.cf.createGroundedCheckBox(w,
                    PRIVATE_COMPUTER, PRIVATE_COMPUTER_TIP, false, "pvt");
        }
        return privateComputer;
    }

    private JPanel assembleAdvancedCenterPanel() {
        JPanel rtn = w.cf.createPanel(new GridLayout(1, 1));
        rtn.add(new JPanel());
        return rtn;
    }

    private JTextArea plainTextTA;

    public JTextArea getPlainTextTA() {
        if (plainTextTA == null) {
            plainTextTA = new JTextArea();
            plainTextTA
                    .setToolTipText(x("Click, paste, or type here to scramble a message."));
            plainTextTA.addKeyListener(new KeyListener() {

                @Override
                public void keyPressed(KeyEvent arg0) {

                }

                @Override
                public void keyReleased(KeyEvent arg0) {
                    encrypt();
                }

                @Override
                public void keyTyped(KeyEvent arg0) {
                }

            });
            plainTextTA.addFocusListener(new FocusListener() {

                @Override
                public void focusGained(FocusEvent arg0) {
                    encrypt();
                }

                @Override
                public void focusLost(FocusEvent arg0) {
                    encrypt();
                }

            });
        }
        return plainTextTA;
    }

    private TitledTextArea encryptedTA;

    public TitledTextArea getEncryptedTA() {
        if (encryptedTA == null) {

            encryptedTA = w.cf.createTitledTextArea(w, x("Scrambled text"),

                    x("Scrambled Text") + " - " + Util.x("Copy and send if sending")
                    + ", "
                    + Util.x("or paste scrambled message here if receiving."), "eta");
            encryptedTA.addKeyListener(new KeyListener() {

                @Override
                public void keyPressed(KeyEvent arg0) {

                }

                @Override
                public void keyReleased(KeyEvent arg0) {
                    decrypt();
                }

                @Override
                public void keyTyped(KeyEvent arg0) {
                }

            });
            encryptedTA.getTextArea().addFocusListener(new FocusListener() {

                @Override
                public void focusGained(FocusEvent arg0) {
                    decrypt();
                }

                @Override
                public void focusLost(FocusEvent arg0) {
                    decrypt();
                }

            });
        }
        return encryptedTA;
    }

    /**
     * Password field.
     */
    private JPasswordField passwordTF;

    private void update() {
        if (isPanicking()) {
            return;
        }
        if (Strings.isPopulated(getEncryptedTA().getText().trim())
                && !Strings.isPopulated(getPlainTextTA().getText().trim())) {
            decrypt();
        } else if (!Strings.isPopulated(getEncryptedTA().getText().trim())
                && Strings.isPopulated(getPlainTextTA().getText().trim())) {
            encrypt();
        }
    }

    protected JPasswordField getPasswordTF() {
        if (passwordTF == null) {
            passwordTF = w.cf.createTitledPasswordField(null,
                    20,
                    x("Password"),
                    x("Use something only you"
                            + " and your friend would ever know."), null);
            passwordTF.addFocusListener(new FocusAdapter() {
                @Override
                public void focusLost(FocusEvent arg0) {
                    update();
                }
            });
            passwordTF.addKeyListener(new KeyAdapter() {
                @Override
                public void keyPressed(KeyEvent e) {
                    if (KeyEvent.VK_ENTER == e.getKeyCode()) {
                        update();
                    }
                }
            });
        }
        return passwordTF;
    }
}
